/******************************************************************************/
/* File: thread.h                                                             */
/******************************************************************************/

#ifndef THREAD_H
#define THREAD_H

#include <pthread.h>
#include <signal.h>
#include <iostream>
#include <unistd.h>
#include <string.h>

/******************************************************************************/
/******************************************************************************/

class Thread {

public:
	enum Attribute {
		StackSize = 0,
		Priority,
	};

	Thread();
	virtual ~Thread();

	pthread_t Self();
	pthread_t GetThreadID();
	bool IsRunning();
	void SetAttribute(enum Attribute a, void *value);
	void GetAttribute(enum Attribute a, void *value);

	void Start(void *arg);
	void Join();
	void Detach();
	void Cancel();
	void Kill(int sig);

    // We define a pure virtual function.
    // Classes inherted from this class must implement the Run methods.
	virtual void Run() = 0;

protected:
    // The ID of this thread.
	pthread_t mTid;
    
	// Thread attribution
	pthread_attr_t mAttr;

	// Store the detach state
	bool bIsDetached;

	// protected functions
	void Exit() {
		pthread_exit(NULL);
	}

	void Exit(void *value) {
		pthread_exit(value);
	}
    
    void *arg;

	static void* exec(void *thr);
};

// 下面是一些与线程同步相关的类，如互斥量/条件变量/临界区/事件等等
/******************************************************************************/
//互斥量封装
/******************************************************************************/
class Mutex {
	
public:
	friend class ConditionVariable;

	Mutex();
	virtual ~Mutex();

	int Lock();
	int Unlock();

private:
	Mutex(const Mutex&);
	Mutex& operator = (const Mutex&);

private:
	pthread_mutex_t mMutex;
};

/******************************************************************************/
//临界区封装
/******************************************************************************/

class CriticalSection {
	
public:
	CriticalSection(Mutex *pMutex);
	virtual ~CriticalSection();

private:
	CriticalSection(const CriticalSection&);
	CriticalSection& operator=(const CriticalSection&);

private:
	Mutex *mpMutex;
};

/******************************************************************************/
//条件变量封装
/******************************************************************************/
class ConditionVariable {
	
public:
	ConditionVariable();
	virtual ~ConditionVariable();

	int Wait(Mutex *pMutex);
	int Wakeup();
	int WakeupAll();

private:
	ConditionVariable(const ConditionVariable&);
	ConditionVariable& operator = (const ConditionVariable&);

private:
	pthread_cond_t mConditionVariable;
};

/******************************************************************************/
//事件封装
/******************************************************************************/
class Event {
	
public: 
	Event( );
	explicit Event(bool bSemaphore);
	virtual ~Event();

public: 
	int Set();
	int Wait();

private:
	Event(const Event&);
	Event& operator = (const Event&);

private:
	Mutex mMutex;
	ConditionVariable mCond;
	int mFlag;
	bool mbSemaphore;
};

// 下面是错误处理类
/******************************************************************************/
//线程错误封装
/******************************************************************************/

class ThreadException {
public:
	enum ErrorCodes {
		errThreadCreate = 0,
		errThreadJoin,
		errThreadDetach,
		errThreadCancel,
		errThreadKill,
		errMutex,
		errCondition,
		errUnknown,
	};

	ThreadException(ErrorCodes ecType);
	ThreadException(const ThreadException &cOriginal);
	~ThreadException();

	void PrintException();

	operator const ErrorCodes() {
		return ecException;
	}

	operator const char *() {
		return pcExceptionString;
	}

private:
	ErrorCodes ecException;

	char *pcExceptionString;

	void SetString(const char *pcErrString);
};

#endif

/******************************************************************************/
/* End File: thread.h                                                         */
/******************************************************************************/